using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Input;
using System.IO;
using System.Xml;

namespace Game1
{
    public class GuiManager
    {
        private List<MenuEntry> MenuEntries;
        private List<MenuEntryTextBox> TextBoxes;
        private List<SubMenu> SubMenus;
        private SpriteFont font;
        private SpriteBatch spriteBatch;
        private Color defaultColor;
        private KeyboardState keystate;
        private bool keyOK = true;
        private static GuiManager guiManager;
        private string curMenu;
        private SubMenu activeSubMenu;
        private Texture2D cursor;
        public bool showCursor = true;
        private Vector2 mouseAdjust = new Vector2(-16, -16);

        private GuiManager()
        {
            font = Base.Content.Load<SpriteFont>("Gui\\GuiFont");
            cursor = Base.Content.Load<Texture2D>("Gui\\cursor");
            spriteBatch = Base.getSpriteBatch();
            defaultColor = Color.White;

            MenuEntries = new List<MenuEntry>();
            TextBoxes = new List<MenuEntryTextBox>();
            SubMenus = new List<SubMenu>();
        }

        public SpriteFont Font
        {
            get { return font; }
        }

        static public GuiManager Singleton
        {
            get
            {
                if (guiManager == null) guiManager = new GuiManager();
                return guiManager;
            }
        }



        public void Draw(GameTime gameTime)
        {
        Finish:

            keystate = Keyboard.GetState();

            spriteBatch.Begin(SpriteBlendMode.AlphaBlend, SpriteSortMode.Deferred, SaveStateMode.SaveState);
            foreach (MenuEntry Entry in MenuEntries)
            {
                spriteBatch.DrawString(font, Entry.getCaption(), Entry.getPosition(), Entry.getColor(), 0.0f, Vector2.Zero, Entry.scale, SpriteEffects.None, 0.0f);
            }

            foreach (MenuEntryTextBox Entry in TextBoxes)
            {
                Entry.update(gameTime);

                spriteBatch.DrawString(font, Entry.getCaption(), Entry.getPosition(), Entry.getColor());

            }

            foreach (SubMenu subMenu in SubMenus)
            {
                subMenu.draw();
            }

            if (showCursor)
            {
                spriteBatch.Draw(cursor, Input.getMousePosition() + mouseAdjust, Color.White);

            }
            spriteBatch.End();

            Keys[] pressed = keystate.GetPressedKeys();
            if (pressed.Length != 0)
            {
                if (keyOK)
                {
                    foreach (MenuEntry entry in MenuEntries)
                    {
                        if (entry.shortcut != null)
                        {

                            foreach (Keys key in pressed)
                            {
                                if (key.ToString() == entry.shortcut)
                                {
                                    if (entry.action == "Goto")
                                    {
                                        string param = entry.param;
                                        this.removeAllEntries();
                                        this.loadFromXML(param);
                                        keyOK = false;
                                        goto Finish;
                                    }
                                }
                            }
                        }
                    }
                    keyOK = false;
                }
            }
            else keyOK = true;
            pressed = null;
        }

        public void AddMenuEntry(MenuEntry newEntry)
        {
            MenuEntries.Add(newEntry);
        }

        public void AddMenuEntry(string Name, string Caption, int X, int Y, float scale, Color color, float dx, float dy)
        {
            MenuEntries.Add(new MenuEntry(Name, Caption, X, Y, scale, color,dx,dy));
        }
        public void AddMenuEntry(string Name, string Caption, int X, int Y, Color color, float dx, float dy)
        {
            MenuEntries.Add(new MenuEntry(Name, Caption, X, Y, 1.0f, color,dx,dy));
        }

        public void AddMenuEntry(string Name, string Caption, int X, int Y, float dx, float dy)
        {
            MenuEntries.Add(new MenuEntry(Name, Caption, X, Y, 1.0f, defaultColor, dx, dy));
        }

        public MenuEntry getEntry(string Name)
        {
            foreach (MenuEntry Entry in MenuEntries)
            {
                if (Entry.getName() == Name) return Entry;

            }
            foreach (MenuEntryTextBox Entry in TextBoxes)
            {
                if (Entry.getName() == Name) return Entry;

            }
            return null;
        }

        public void removeEntry(string Name)
        {
            MenuEntries.Remove(getEntry(Name));
            TextBoxes.Remove(getEntry(Name) as MenuEntryTextBox);
        }

        public void removeAllEntries()
        {
            MenuEntries.Clear();
            TextBoxes.Clear();
            SubMenus.Clear();
        }

        /*     public void addTextBox(string Name,float X,float Y,Color color)
             {
                 TextBoxes.Add(new MenuEntryTextBox(Name, X, Y, color));
             }*/

        public void AddMenuEntry(MenuEntryTextBox newEntry)
        {
            TextBoxes.Add(newEntry);
        }

        public string getCurrentGui()
        {
            return curMenu;
        }

        public void loadFromXML(string filename)
        {
            //  XmlTextWriter writer = new XmlTextWriter(new StreamWriter("test.xml"));
            XmlTextReader reader = new XmlTextReader(filename + ".jan");
            curMenu = filename;
            while (reader.Read())
            {
                if (reader.Name == "MenuEntry")
                {
                    string name = null;
                    string caption = null;
                    Vector2 offset = Vector2.Zero;
                    Color color = Color.White;
                    string shortcut = null;
                    string action = null;
                    string param = null;

                    do
                    {
                        reader.Read();
                        if (reader.Name == "Entry")
                        {
                            name = reader.GetAttribute("Name");
                            caption = reader.GetAttribute("Caption");
                        }
                        if (reader.Name == "Offset") offset = new Vector2(int.Parse(reader.GetAttribute("X")),
                                                                     int.Parse(reader.GetAttribute("Y")));
                        if (reader.Name == "Color") color = new Color(byte.Parse(reader.GetAttribute("R")),
                                                               byte.Parse(reader.GetAttribute("G")),
                                                               byte.Parse(reader.GetAttribute("B")),
                                                               byte.Parse(reader.GetAttribute("A")));
                        if (reader.Name == "Relative")
                            offset = new Vector2(float.Parse(reader.GetAttribute("X")) * Base.Window.ClientBounds.Width / 10,
                                                 float.Parse(reader.GetAttribute("Y")) * Base.Window.ClientBounds.Height / 10);
                        if (reader.Name == "Shortcut") shortcut = reader.GetAttribute("Key");
                        if (reader.Name == "Action")
                        {
                            action = reader.GetAttribute("Act");
                            param = reader.GetAttribute("Param");
                        }

                        //int a = netTestMain.Window.ClientBounds.Width;
                    } while (reader.Name != "MenuEntry");

                    AddMenuEntry(name, caption, (int)offset.X, (int)offset.Y, color,35,25);
                    getEntry(name).shortcut = shortcut;
                    getEntry(name).action = action;
                    getEntry(name).param = param;
                }
            }
        }

        public SubMenu createSubMenu(string nome, int offsetX, int offsetY, Color activeColor, Color normalColor)
        {
            SubMenu novo = new SubMenu(nome, offsetX, offsetY, activeColor, normalColor);
            SubMenus.Add(novo);
            activeSubMenu = novo;
            return novo;
        }

        public SubMenu createSubMenu(string nome, Color activeColor, Color normalColor)
        {
            SubMenu novo = new SubMenu(nome, 0, 0, activeColor, normalColor);

            SubMenus.Add(novo);
            activeSubMenu = novo;
            return novo;
        }

        public SubMenu createSubMenu(string nome)
        {
            SubMenu novo = new SubMenu(nome, 0, 0, Color.White, Color.Black);
            SubMenus.Add(novo);
            activeSubMenu = novo;
            return novo;
        }

        public SubMenu getSubMenu(string name)
        {
            foreach (SubMenu subMenu in SubMenus)
            {
                if (subMenu.Name == name) return subMenu;
            }
            return null;
        }

        public void setActiveSubMenu(string name)
        {
            foreach (SubMenu subMenu in SubMenus)
            {
                if (subMenu.Name == name)
                {
                    activeSubMenu.Active = false;
                    activeSubMenu = subMenu;
                    subMenu.Active = true;
                    subMenu.Visible = true;
                }
            }
        }

        public SubMenu getActiveSubMenu()
        {
            return activeSubMenu;
        }

        public void selectUp()
        {
            activeSubMenu.selectUp();
        }

        public void selectDown()
        {
            activeSubMenu.selectDown();
        }
        public void selectFromMouse()
        {
            activeSubMenu.selectFromMouse();
        }
        public bool mouseClickedOnSelected()
        {
            if (Input.isMouseClicked(MouseButton.LeftButton) && getActiveSubMenu().getSelected().verifyMouseInSquare()) return true;
            return false;
        }
    }
}

